package com.sky.service.impl;


import com.sky.mapper.OrderMapper;
import com.sky.mapper.userMapper;
import com.sky.service.ReportService;
import com.sky.service.WorkService;
import com.sky.vo.*;
import org.apache.commons.lang.StringUtils;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Service;


import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class ReportServiceImpl implements ReportService {
    @Autowired
    private OrderMapper orderMapper;
    @Autowired
    private userMapper userMapper;
    @Autowired
    private WorkService workService;
    @Override
    public TurnoverReportVO turnoverStatistics(LocalDate begin, LocalDate end) {
        List<LocalDate> dateList = new ArrayList<>();
        int starts=5;
        while (!begin.equals(end)){
            dateList.add(begin);
            begin = begin.plusDays(1);
        }
        int total = 0;
        dateList.add(end);
        List<Double> turnoverList = new ArrayList<>();
        for (LocalDate s : dateList) {
            LocalDateTime beginTime = LocalDateTime.of(s, LocalDateTime.MIN.toLocalTime());
            LocalDateTime endTime = LocalDateTime.of(s, LocalDateTime.MAX.toLocalTime());
            Double discount =orderMapper.getTurnover(beginTime,endTime,starts);
            if (discount == null){
                turnoverList.add(0.0);

            }else {
                turnoverList.add(discount);
                total += discount;
            }
            }
        return new TurnoverReportVO().builder().dateList(StringUtils.join(dateList, ",")).turnoverList(StringUtils.join(turnoverList, ",")).totalTurnover(total).build();
        }

    @Override
    public OrderReportVO ordersStatistics(LocalDate begin, LocalDate end) {
        List<LocalDate> dateList = new ArrayList<>();
        int starts=6;
        while (!begin.equals(end)){
            dateList.add(begin);
            begin = begin.plusDays(1);
        }
        dateList.add(end);
        List<Integer> orderCountlist= new ArrayList<>();
        List<Integer> validorderCountlist = new ArrayList<>();
        int totalOrderCount = 0; int validOrderCount = 0;
        for (LocalDate s : dateList) {
            LocalDateTime beginTime = LocalDateTime.of(s, LocalDateTime.MIN.toLocalTime());
            LocalDateTime endTime = LocalDateTime.of(s, LocalDateTime.MAX.toLocalTime());
            Integer oC =orderMapper.OrderCount(beginTime,endTime);
            if (oC == null) {
                oC = 0; // 处理空值情况
            }
            int orderCount = oC;
            totalOrderCount += orderCount;
            Integer cC =orderMapper.cancelCount(beginTime,endTime);
            if (cC == null) {
                cC = 0; // 处理空值情况
            }
            int validorderCount =orderCount-cC;
            validOrderCount += validorderCount;
            orderCountlist.add(orderCount);
            validorderCountlist.add(validorderCount);
        }
        return new OrderReportVO().builder().dateList(StringUtils.join(dateList, ",")).orderCountList(StringUtils.join(orderCountlist, ",")).validOrderCountList(StringUtils.join(validorderCountlist, ",")).totalOrderCount(totalOrderCount).validOrderCount(validOrderCount).orderCompletionRate(validOrderCount * 1.0 / totalOrderCount).build();
    }

    @Override
    public UserReportVO userStatistics(LocalDate begin, LocalDate end) {
        List<LocalDate> dateList = new ArrayList<>();
        while (!begin.equals(end)){
            dateList.add(begin);
            begin = begin.plusDays(1);
        }
        dateList.add(end);

// 获取开始日期之前的总用户数
        LocalDate end0 = dateList.get(0).minusDays(1);
        int userCount = userMapper.findbydate(null, LocalDateTime.of(end0, LocalDateTime.MAX.toLocalTime()));
        int uc1=userCount;
// 用于记录每天的数据
        List<Integer> totalUserList = new ArrayList<>();
        List<Integer> newUserList = new ArrayList<>();

        for (LocalDate s : dateList) {
            LocalDateTime beginTime = LocalDateTime.of(s, LocalDateTime.MIN.toLocalTime());
            LocalDateTime endTime = LocalDateTime.of(s, LocalDateTime.MAX.toLocalTime());

            // 获取当天的新增用户数
            Integer oC = userMapper.findbydate(beginTime, endTime);
            if (oC == null) {
                oC = 0; // 处理空值情况
            }

            // 更新总用户数和新增用户数
            userCount += oC;
            totalUserList.add(userCount);  // 总用户数
            newUserList.add(oC);  // 新增用户数
        }

        return new UserReportVO().builder()
                .dateList(StringUtils.join(dateList, ","))
                .totalUserList(StringUtils.join(totalUserList, ","))
                .newUserList(StringUtils.join(newUserList, ","))
                .newUser(userCount - uc1)
                .build();

    }

    @Override
    public SalesTop10ReportVO top10(LocalDate begin, LocalDate end) {
        LocalDateTime beginTime = LocalDateTime.of(begin, LocalDateTime.MIN.toLocalTime());
        LocalDateTime endTime = LocalDateTime.of(end, LocalDateTime.MAX.toLocalTime());
        List<Map<String, Object>> map =orderMapper.findtop10(beginTime, endTime);
        List<Object> nameList = map.stream()
                .map(dataMap -> dataMap.get("name"))
                .collect(Collectors.toList());

        List<Object> numberList = map.stream()
                .map(dataMap -> dataMap.get("total"))
                .collect(Collectors.toList());
        return new SalesTop10ReportVO().builder().nameList(StringUtils.join(nameList, ",")).numberList(StringUtils.join(numberList, ",")).build();
    }

    @Override
    public void export(HttpServletResponse response) {
        BusinessDataVO businessDataVO = workService.businessData(LocalDate.now().minusDays(30), LocalDate.now().minusDays(1));

        InputStream resourceAsStream = this.getClass().getClassLoader().getResourceAsStream("template/运营数据报表模板.xlsx");
        try {
            XSSFWorkbook excel = new XSSFWorkbook(resourceAsStream);
            XSSFSheet sheet = excel.getSheet("Sheet1");
            sheet.getRow(1).getCell(1).setCellValue("时间："+LocalDate.now().minusMonths(1)+"-"+LocalDate.now().minusDays(1));
            sheet.getRow(3).getCell(2).setCellValue(businessDataVO.getTurnover());
            sheet.getRow(3).getCell(4).setCellValue(businessDataVO.getOrderCompletionRate());
            sheet.getRow(3).getCell(6).setCellValue(businessDataVO.getNewUsers());
            sheet.getRow(4).getCell(2).setCellValue(businessDataVO.getValidOrderCount());
            sheet.getRow(4).getCell(4).setCellValue(businessDataVO.getUnitPrice());
            LocalDate date1 = LocalDate.now().minusDays(30);
            for (int i = 0; i <30 ; i++) {
                LocalDate date2 = date1.plusDays(1);
                BusinessDataVO businessDataVO1 = workService.businessData(date1,date2);
                sheet.getRow(i+7).getCell(1).setCellValue(String.valueOf(date1));
                sheet.getRow(i+7).getCell(2).setCellValue(businessDataVO1.getTurnover());

                sheet.getRow(i+7).getCell(6).setCellValue(businessDataVO1.getNewUsers());
                sheet.getRow(i+7).getCell(3).setCellValue(businessDataVO1.getValidOrderCount());
                if(businessDataVO1.getValidOrderCount()!=0){
                sheet.getRow(i+7).getCell(4).setCellValue(businessDataVO1.getOrderCompletionRate());
                sheet.getRow(i+7).getCell(5).setCellValue(businessDataVO1.getUnitPrice());}
                else {
                    sheet.getRow(i+7).getCell(4).setCellValue("当日无订单");
                    sheet.getRow(i+7).getCell(5).setCellValue("当日无订单");
                }
                date1 = date1.plusDays(1);
            }
            ServletOutputStream outputStream = response.getOutputStream();
            excel.write(outputStream);

        } catch (IOException e) {
            throw new RuntimeException(e);
        }

    }


}

